package com.yungu.swift.lbs.trace.gaode;

import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.collect.Lists;
import com.yungu.swift.lbs.model.Point;
import com.yungu.swift.lbs.model.param.TrsearchParam;
import com.yungu.swift.lbs.model.vo.TrackVo;
import com.yungu.swift.utils.HttpUtils;
import com.yungu.swift.utils.JsonUtils;
import com.yungu.swift.utils.ParamUtil;
import com.yungu.swift.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 高德猎鹰——轨迹服务
 *
 * @author : cuixiuyin
 * @date : 2019/5/27
 */
@Slf4j
public class TraceUtils {


    /**
     * 请求成功
     */
    private static final Integer SUCCESS_CODE = 10000;
    /**
     * 部分点上传失败
     */
    private static final Integer PARTIAL_SUCCESS = 20100;
    /**
     * 所有点上传失败
     */
    private static final Integer NOTHING_SUCCESS = 20101;
    private static final String SUCCESS_MSG = "OK";


    /**
     * 创建轨迹
     *
     * @param key 高德 key
     * @param sid 高德 sid
     * @param tid 终端 tid
     * @return
     */
    public static Long createTrace(String key, String sid, Long tid) {
        if (ParamUtil.isIllegal(key, sid, tid)) {
            return 0L;
        }
        Map<String, Object> paramMap = new HashMap<>(4);
        paramMap.put("key", key);
        paramMap.put("sid", sid);
        paramMap.put("tid", tid);
        Map<String, Object> objectMap = HttpUtils.post("https://tsapi.amap.com/v1/track/trace/add", paramMap);
        Object result = objectMap.get("result");
        if (result != null) {
            try {
                JsonNode jsonNode = JsonUtils.readNode(result.toString());
                int errcode = jsonNode.get("errcode").asInt();
                String errmsg = jsonNode.get("errmsg").asText();
                if (errcode == SUCCESS_CODE && SUCCESS_MSG.equals(errmsg)) {
                    JsonNode data = jsonNode.get("data");
                    JsonNode trid = data.get("trid");
                    if (trid != null) {
                        return trid.asLong();
                    }
                }
            } catch (IOException e) {
                log.error("TraceUtils createTrace error,result:{}", result, e);
            }
        }
        return 0L;
    }


    /**
     * 上传轨迹点
     *
     * @param key 高德 key
     * @param sid 高德 sid
     * @param tid 终端 tid
     * @return 上传的错误点数，如果 list 为空说明全部上传成功
     */
    public static List<Point> uploadPoints(String key, String sid, Long tid, Long trid, List<Point> points) {
        if (ParamUtil.isIllegal(key, sid, tid, trid)) {
            return Lists.newArrayList();
        }
        Map<String, Object> paramMap = new HashMap<>(8);
        paramMap.put("key", key);
        paramMap.put("sid", sid);
        paramMap.put("tid", tid);
        paramMap.put("trid", trid);
        paramMap.put("points", JsonUtils.toJSONString(points));
        Map<String, Object> objectMap = HttpUtils.post("https://tsapi.amap.com/v1/track/point/upload", paramMap);
        Object result = objectMap.get("result");
        if (result != null) {
            try {
                JsonNode jsonNode = JsonUtils.readNode(result.toString());
                int errcode = jsonNode.get("errcode").asInt();
                if (errcode == PARTIAL_SUCCESS || errcode == NOTHING_SUCCESS) {
                    JsonNode data = jsonNode.get("data");
                    JsonNode errorpoints = data.get("errorpoints");
                    if (errorpoints != null) {
                        return JsonUtils.readListValue(errorpoints.toString(), Point.class);
                    }
                }
            } catch (IOException e) {
                log.error("TraceUtils uploadPoints error,result:{}", result, e);
            }
        }
        return Lists.newArrayList();
    }


    public static List<TrackVo> trsearch(String key, String sid, Long tid, Long trid, TrsearchParam trsearchParam) {
        if (ParamUtil.isIllegal(key, sid, tid, trid)) {
            return null;
        }
        StringBuffer stringBuffer = new StringBuffer("?");
        stringBuffer.append("key=" + key + "&");
        stringBuffer.append("sid=" + sid + "&");
        stringBuffer.append("tid=" + tid + "&");
        stringBuffer.append("trid=" + trid + "&");
        //denoise - 抽稀去噪 、 mapmatch - 绑路纠偏、attribute - 属性拟合 threshold - 定位精度过滤
        stringBuffer.append("correction=denoise=1,mapmatch=1,attribute=0,threshold=0,mode=driving&");
        // 是否进行补点
        stringBuffer.append("recoup=1&");
        // 补点距离 单位（米）
        stringBuffer.append("gap=500&");
        if (trsearchParam == null) {
            trsearchParam = new TrsearchParam();
        }
        if (trsearchParam.getStarttime() != null) {
            stringBuffer.append("starttime=" + trsearchParam.getStarttime().getTime() + "&");
        }
        if (trsearchParam.getEndtime() != null) {
            stringBuffer.append("endtime=" + trsearchParam.getEndtime().getTime() + "&");
        }
        if (trsearchParam.getPage() != null) {
            stringBuffer.append("page=" + trsearchParam.getPage() + "&");
        }
        if (trsearchParam.getPagesize() != null) {
            stringBuffer.append("pagesize=" + trsearchParam.getPagesize() + "&");
        }
        Map<String, Object> objectMap = HttpUtils.get("https://tsapi.amap.com/v1/track/terminal/trsearch" +
                StringUtils.removeEnd(stringBuffer.toString(), "&"));
        Object result = objectMap.get("result");
        if (result != null) {
            try {
                JsonNode jsonNode = JsonUtils.readNode(result.toString());
                int errcode = jsonNode.get("errcode").asInt();
                String errmsg = jsonNode.get("errmsg").asText();
                if (errcode == SUCCESS_CODE && SUCCESS_MSG.equals(errmsg)) {
                    JsonNode data = jsonNode.get("data");
                    JsonNode tracks = data.get("tracks");
                    if (tracks != null) {
                        return JsonUtils.readListValue(tracks.toString(), TrackVo.class);
                    }
                }
            } catch (IOException e) {
                log.error("TraceUtils trsearch error,result:{}", result, e);
            }

        }
        return Lists.newArrayList();
    }
}
